package cn.sangyy.car.service.impl;

import cn.sangyy.basic.common.code.CodeEnum;
import cn.sangyy.basic.constent.BaseConstants;
import cn.sangyy.basic.exception.BusinessException;
import cn.sangyy.basic.exception.CarAssert;
import cn.sangyy.basic.utils.AjaxResult;
import cn.sangyy.basic.utils.BaiduAuditUtils;
import cn.sangyy.basic.utils.PageList;
import cn.sangyy.basic.utils.VelocityUtils;
import cn.sangyy.car.doc.CarDoc;
import cn.sangyy.car.domain.Car;
import cn.sangyy.car.domain.CarDetail;
import cn.sangyy.car.domain.CarOperationLog;
import cn.sangyy.car.domain.CarType;
import cn.sangyy.car.mapper.CarDetailMapper;
import cn.sangyy.car.mapper.CarMapper;
import cn.sangyy.car.mapper.CarOperationLogMapper;
import cn.sangyy.car.mapper.CarTypeMapper;
import cn.sangyy.car.query.CarQuery;
import cn.sangyy.car.repository.CarRepository;
import cn.sangyy.car.service.ICarService;
import cn.sangyy.org.domain.Employee;
import cn.sangyy.org.domain.Shop;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.sun.mail.imap.protocol.BODY;
import com.sun.org.apache.xpath.internal.operations.Bool;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author sangyangyang
 * @since 2023-05-26
 */
@Service
public class CarServiceImpl extends ServiceImpl<CarMapper, Car> implements ICarService {

    @Autowired
    private CarMapper carMapper;
    @Autowired
    private CarOperationLogMapper logMapper;
    @Autowired
    private CarDetailMapper carDetailMapper;
    @Autowired
    private CarRepository carRepository;

    @Value("${carDetail.templatePath}")
    private String templatePath;
    @Value("${carDetail.targetPath}")
    private String targetPath;

    @Override
    public PageList<Car> getPageList(CarQuery query) {
        Page<Car> carPage = new Page<>(query.getPage(),query.getRows());
        List<Car> rows = carMapper.getPageList(carPage,query);
        return new PageList<>(carPage.getTotal(),rows);
    }

    @Override
    @Transactional
    public void insert(Car car, Employee employee) {
        //设置店铺信息 销售人员，所属店铺，创建时间，类型
        car.setShopId(employee.getShop().getId());
        car.setShopname(employee.getShop().getName());
        car.setCreatetime(new Date());
        //状态默认下架
        car.setState(BaseConstants.carState.CAR_STATE_OFFLINE);
        car.setSellerId(employee.getId());
        //信息审核(名字，图片，基本信息)，设置审核状态
        String context = car.getTitle()+","+car.getCarDetail().getInfo();
        Map<String, Object> map = BaiduAuditUtils.censor(context, car.getCover());
        Boolean success = (Boolean) map.get("success");
        CarOperationLog carOperationLog = new CarOperationLog();
        if(success){
            car.setAuditstate(BaseConstants.carAuditState.CAR_AUDIT_STATE_SUCCESS);
            carOperationLog.setOperationType(BaseConstants.carOperationLogType.CAR_OPERATION_LOG_TYPE_AUDIT_SUCCESS);
            carOperationLog.setNote("系统审核通过！");
        }else {
            car.setAuditstate(BaseConstants.carAuditState.CAR_AUDIT_STATE_FAIL);
            carOperationLog.setOperationType(BaseConstants.carOperationLogType.CAR_OPERATION_LOG_TYPE_AUDIT_FAIL);
            String message = map.get("message").toString();
            carOperationLog.setNote(message);
        }
        super.insert(car);
        addDetailAndLog(car, carOperationLog);
    }

    private void addDetailAndLog(Car car, CarOperationLog carOperationLog) {
        carOperationLog.setCarId(car.getId());
        carOperationLog.setOperationId(0L);
        carOperationLog.setOperationTime(new Date());
        logMapper.insert(carOperationLog);
        if(Objects.nonNull(car.getCarDetail())){
            CarDetail carDetail = new CarDetail();
            carDetail.setCarId(car.getId());
            carDetail.setInfo(car.getCarDetail().getInfo());
            carDetail.setCartitle(car.getTitle());
            carDetailMapper.insert(carDetail);
        }
    }

    @Transactional
    public AjaxResult updateCar(Car car) {
        //信息审核
        String cover = car.getCover();
        Integer auditState = car.getAuditstate();
        String context = car.getTitle()+","+car.getCarDetail().getInfo();
        Map<String, Object> map = BaiduAuditUtils.censor(context, cover);
        Boolean success = (Boolean)map.get("success");
        CarOperationLog log;
        if(success){
            CarDetail carDetail = car.getCarDetail();
            //修改基本信息
            carDetailMapper.updateInfo(carDetail);
            //修改car信息
            if(auditState == BaseConstants.carAuditState.CAR_AUDIT_STATE_FAIL) {
                car.setAuditstate(BaseConstants.carAuditState.CAR_AUDIT_STATE_SUCCESS);
            }
            carMapper.updateInfo(car);
            //审核成功，添加审核日志
            log = new CarOperationLog();
            log.setCarId(car.getId());
            log.setOperationType(1);
            log.setOperationTime(new Date());
            log.setOperationId(0L);
            log.setNote("修改信息成功，系统审核通过！");
            logMapper.insert(log);
            return AjaxResult.me();
        }else {
            //审核不过，添加审核日志
            log = new CarOperationLog();
            log.setCarId(car.getId());
            log.setOperationType(2);
            log.setOperationTime(new Date());
            log.setOperationId(0L);
            Object message = map.get("message");
            String note = "修改信息失败，系统审核不通过！"+message.toString();
            log.setNote(note);
            logMapper.insert(log);
            return AjaxResult.me().setCode(201).setResultObj(note);
        }
    }

    @Override
    @Transactional
    public String batchOnSale(List<Long> ids,Employee loginUser) {
        //空校验
        CarAssert.assertListNotNull(ids, CodeEnum.ON_SALE_NUM_EMPTY);
        //查询上架车辆信息
        List<Car> carList = carMapper.selectBatch(ids);
        //筛选判断审核状态和上下架状态
        List<Car> realList = carList.stream().filter(c -> c.getAuditstate() == BaseConstants.carAuditState.CAR_AUDIT_STATE_SUCCESS
                && c.getState() == BaseConstants.carState.CAR_STATE_OFFLINE).collect(Collectors.toList());
        //如果都不符合上架要求
        CarAssert.assertListNotNull(realList,CodeEnum.OFF_SALE_REAL_NUM_EMPTY);
        //处理更新数据库上架信息
        String message = "上架成功"+realList.size()+"条,失败"+(carList.size()-realList.size())+"条";
        //修改上架状态和上架时间
        ids = realList.stream().map(c -> c.getId()).collect(Collectors.toList());
        carMapper.updateOnSaleInfo(ids,BaseConstants.carState.CAR_STATE_ONLINE);
        //操作日志
        BatchInsertLog(loginUser, ids,BaseConstants.carState.CAR_STATE_ONLINE);
        //更新es
        List<CarDoc> docs = saveCarToES(realList);
        carRepository.saveAll(docs);
        //生成每个车辆的静态页面...
        for (CarDoc doc : docs) {
            String url = this.targetPath+doc.getId()+".html";
            VelocityUtils.staticByTemplate(doc,this.templatePath,url);
        }
        return message;
    }

    private List<CarDoc> saveCarToES(List<Car> realList) {
        List<CarDoc> docs = new ArrayList<>(realList.size());
        realList.forEach(c -> {
            CarDoc carDoc = new CarDoc();
            BeanUtils.copyProperties(c,carDoc);
            Shop shop = c.getShop();
            CarType type = c.getType();
            CarDetail carDetail = c.getCarDetail();
            Employee seller = c.getSeller();
            if(Objects.nonNull(shop)){
                carDoc.setShopId(shop.getId());
                carDoc.setShopName(shop.getName());
                carDoc.setShopAddress(shop.getAddress());
            }
            if(Objects.nonNull(type)){
                carDoc.setTypeName(type.getName());
            }
            if(Objects.nonNull(carDetail)){
                carDoc.setCarInfo(carDetail.getInfo());
            }
            if(Objects.nonNull(seller)){
                carDoc.setSellerName(seller.getRealName());
            }
            docs.add(carDoc);
        });
        return docs;
    }

    private void BatchInsertLog(Employee loginUser, List<Long> ids,Integer state) {
        List<CarOperationLog> logs = new ArrayList<>(ids.size());
        Long userId = loginUser.getId();
        String s;
        Integer type;
        if(state == BaseConstants.carState.CAR_STATE_ONLINE){
            s = "上架";
            type = BaseConstants.carOperationLogType.CAR_OPERATION_LOG_TYPE_ONLINE;
        }else {
            s = "下架";
            type = BaseConstants.carOperationLogType.CAR_OPERATION_LOG_TYPE_OFFLINE;
        }
        for (Long id : ids) {
            CarOperationLog log = new CarOperationLog();
            log.setCarId(id);
            log.setOperationId(userId);
            log.setOperationTime(new Date());
            log.setOperationType(type);
            log.setNote(s+"了carId为"+id+"的车俩");
            logs.add(log);
        }
        logMapper.batchInsert(logs);
    }

    @Override
    @Transactional
    public void batchOffSale(List<Long> ids,Employee loginUser) {
        //空校验
        CarAssert.assertListNotNull(ids, CodeEnum.OFF_SALE_NUM_EMPTY);
        //修改下架状态和下架时间
        carMapper.updateOnSaleInfo(ids,BaseConstants.carState.CAR_STATE_OFFLINE);
        //添加操作日志
        BatchInsertLog(loginUser, ids,BaseConstants.carState.CAR_STATE_OFFLINE);
        //更新es
        for (Long id : ids) {
            carRepository.deleteById(id);
        }
        //删除每个车辆的静态页面...
        for (Long id : ids) {
            String filePath = this.targetPath+id+".html";
            File file = new File(filePath);
            if(file.exists()){
                file.delete();
            }
        }
    }
}
